#include "SpeechModuleThread.h"

extern QString currentStep;
extern int expStatus;
extern QMap<int,QVariantMap> expLogInfo;
extern QMap<int,QVariantMap> expSendList;
extern int expStep;
extern QString expName;
extern double totalExpTime;
extern QStringList runningList;

speechModuleThread::speechModuleThread(QObject *parent): QObject(parent)
{
    this->moveToThread(&thread);
    serialPort = new QSerialPort(this);
    thread.start();
    serialinfo();
}

void speechModuleThread::serialinfo()
{
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql="Select * From SpeechMode";
    query.exec(sql);
    QString serialNamePort;
    bool isUse;
    while (query.next())
    {
        serialNamePort=query.value("SerialPort").toString();
        isUse=query.value("IsUse").toString()=="1";
    }
    if(isUse){
        if(serialPort->isOpen()){
            serialPort->close();
        }else{
            QSerialPort::BaudRate baudRate;
            baudRate = QSerialPort::Baud115200;
            serialPort->setPortName(serialNamePort);
            serialPort->setBaudRate(baudRate);
            if(serialPort->open(QIODevice::ReadWrite)){
                QMLSignal::I().emitVoiceAssistant(0);     // 发信号通知前端
            }else{
                QMLSignal::I().emitVoiceAssistant(1);     // 发信号通知前端
            }
            connect(serialPort,SIGNAL(readyRead()),this,SLOT(serialPortRead_Slot()));// 串口读取
        }
    }
    else{
        QMLSignal::I().emitVoiceAssistant(1);     // 发信号通知前端
    }
}

void speechModuleThread::stop()
{
    qDebug()<<serialPort->isOpen();
    if (serialPort->isOpen()) {
        serialPort->close(); // 关闭串口
    }
}

void speechModuleThread::run()
{
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql="Select * From SpeechMode";
    query.exec(sql);
    QString serialNamePort;
    bool isUse;
    while (query.next())
    {
        serialNamePort=query.value("SerialPort").toString();
        isUse=query.value("IsUse").toString()=="1";
    }
    if(isUse){
        serialinfo();
    }
}

// 接收消息
void speechModuleThread::serialPortRead_Slot()
{
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql="Select * From SpeechMode";
    query.exec(sql);
    QString serialNamePort;
    bool isUse;
    while (query.next())
    {
        serialNamePort=query.value("SerialPort").toString();
        isUse=query.value("IsUse").toString()=="1";
    }
    if(isUse){
        udpClient=UdpClient::getInstance();
        QByteArray buffer = serialPort->readAll();
        QString ss;
        for(int c :buffer)
        {
            if(c>=0)
            {
                ss += QString(" %1")
                        .arg(c, 2, 16, QChar('0'));
            }
            else
            {
                ss += QString(" %1")
                        .arg(c+256, 2, 16, QChar('0'));
            }
        }
        QString Data=ss.remove(QRegExp("\\s"));
        if(Data=="0001"){
            //exe_config 0实验信息 1注射器 2阀门 3转盘 4等待 5检测器 6循环 7跳过 8盖盖 9气泵
            expSendList.clear();

            QSqlDatabase db = dbHelper::openConnection();
            QSqlQuery query(db);

            QString id;
            QString sql;
            QString code=common->getItemCode("3",expConsumablesType);
            sql=QString("Select Id From exe_config Where value_1='%1' and value_2='%2' and type='0'").arg(expName,code);

            //获取实验ID
            query.exec(sql);
            while (query.next()) {
                id=query.value("ID").toString();
            }

            QMap<QString,QVariantMap> circleStepList;

            sql=QString("Select * From exe_config Where Id='%1' and type='6' order by Step ").arg(id);
            query.exec(sql);
            while (query.next())
            {
                QVariantMap map;
                map["Begin"]=query.value("value_1").toString();
                map["End"]=query.value("value_2").toString();
                map["CircleNum"]=query.value("value_3").toString();
                map["Step"]=query.value("step").toString();
                circleStepList.insert(query.value("value_1").toString(),map);
            }

            QList<QVariantMap> exeConfigList;

            sql=QString("Select * From exe_Config Where id='%1' and Type<>'0' order by Step").arg(id);
            query.exec(sql);
            while (query.next()) {
                QVariantMap map;
                for (int i = 0; i < query.record().count(); ++i) {
                    map[query.record().fieldName(i)] = query.value(i);
                }
                exeConfigList.append(map);
            }
            totalExpTime=0;
            int step=1;
            for(int i=0;i<exeConfigList.length();i++){
                if(circleStepList.contains(exeConfigList[i].value("step").toString()))
                {
                    QVariantMap beginMap;
                    beginMap["Type"]="1";//0 正常执行(Info发送指令) 1循环(开始循环,结束循环) 2 跳过("") 3等待(等待时长)
                    beginMap["Step"]=circleStepList[exeConfigList[i].value("step").toString()]["Step"].toString();
                    beginMap["Info"]="开始循环";
                    expSendList.insert(step,beginMap);
                    step++;

                    QString endNum= circleStepList[exeConfigList[i].value("step").toString()]["End"].toString();
                    int circleNum= circleStepList[exeConfigList[i].value("step").toString()]["CircleNum"].toInt();

                    for(int a=0;a<circleNum;a++){
                        for(int m=exeConfigList[i].value("step").toInt();m<=endNum.toInt();m++)
                        {
                            QVariantMap map;
                            QString type=exeConfigList[m-1].value("type").toString();

                            if(type=="1")//注射器
                            {
                                QString sql=QString("Select InsideDiameter,ReductionRatio,ScrewLead,CircleStep From SyringeMaintenance Where ConsumablesTypes='%1' and Id='%2'").arg(code,exeConfigList[m-1].value("value_1").toString());
                                query.exec(sql);
                                double InsideDiameter,ScrewLead,CircleStep;
                                QString ReductionRatio;
                                while (query.next()) {
                                    InsideDiameter=query.value("InsideDiameter").toDouble();
                                    ReductionRatio=query.value("ReductionRatio").toString();
                                    ScrewLead=query.value("ScrewLead").toDouble();
                                    CircleStep=query.value("CircleStep").toDouble();
                                }
                                double speed=exeConfigList[m-1].value("value_8").toDouble();

                                // 速度单位:ml/分
                                if(exeConfigList[m-1].value("value_9")=="mL/Min")
                                {
                                    speed=common->minToSecond(QString::number(speed),QString::number(InsideDiameter)).toDouble();
                                }

                                QStringList reList=ReductionRatio.split(':');

                                double stepNum=exeConfigList[m-1].value("value_6").toDouble()/ScrewLead*CircleStep*reList[1].toDouble();
                                double time=exeConfigList[m-1].value("value_6").toDouble()/speed;
                                double stepNumber = stepNum/time;
                                map["Type"]="0";//0 正常执行(Info发送指令) 1循环(开始循环,结束循环) 2 跳过("") 3等待(等待时长) 4检测器
                                map["Step"]=exeConfigList[m-1].value("step").toString();
                                map["Info"]=CommCommand::I().getSyring(QString::number(step),exeConfigList[m-1].value("value_1").toString(),exeConfigList[m-1].value("value_4").toString(),QString::number(stepNumber),QString::number(stepNum));
                                totalExpTime+=time;

                                expSendList.insert(step,map);
                                step++;
                            }
                            else if(type=="2")//阀门
                            {
                                map["Type"]="0";
                                map["Step"]=exeConfigList[m-1].value("step").toString();
                                map["Info"]= CommCommand::I().getValve(QString::number(step),exeConfigList[m-1].value("value_1").toString(),exeConfigList[m-1].value("value_2").toString());
                                totalExpTime+=1;

                                expSendList.insert(step,map);
                                step++;
                            }
                            else if(type=="3")//转盘
                            {
                                map["Type"]="0";
                                map["Step"]=exeConfigList[m-1].value("Step").toString();
                                map["Info"]=map["Info"]=CommCommand::I().getTurntable(QString::number(step),exeConfigList[m-1].value("value_1").toString());

                                totalExpTime+=1;

                                expSendList.insert(step,map);
                                step++;
                            }
                            else if(type=="4")//检测器
                            {
                                map["Type"]="4";
                                map["Step"]=exeConfigList[m-1].value("step").toString();
                                map["Info"]="";
                            }
                            else if(type=="5")//等待
                            {
                                map["Type"]="3";
                                map["Step"]=exeConfigList[m-1].value("Step").toString();
                                map["Info"]=query.value("Value_1").toString();
                                totalExpTime+=query.value("Value_1").toDouble();

                                expSendList.insert(step,map);
                                step++;
                            }
                            else if(type=="7")//跳过
                            {
                                for(int n=0;n<=exeConfigList[m-1].value("Value_1").toInt();n++)
                                {
                                    QVariantMap map;
                                    map["Type"]="2";//0 正常执行(Info发送指令) 1循环(开始循环,结束循环) 2 跳过("") 3等待(等待时长)
                                    map["Step"]=QString::number(exeConfigList[m-1].value("Step").toInt()+n);
                                    map["Info"]="";
                                    expSendList.insert(step,map);
                                    step++;
                                }
                                m=exeConfigList[m-1].value("Step").toInt()+exeConfigList[m-1].value("Value_1").toInt();
                            }
                            else if(type=="8")//盖盖
                            {
                                if(exeConfigList[m-1].value("value_1").toString()=="是")
                                {
                                    map["Type"]="0";
                                    map["Step"]=exeConfigList[m-1].value("step").toString();
                                    map["Info"]=CommCommand::I().coverTheLid(QString::number(step));
                                    expSendList.insert(step,map);
                                    totalExpTime+=2;

                                }
                                step++;
                            }
                        }

                        QVariantMap map;
                        map["Type"]="1";//0 正常执行(Info发送指令) 1循环(开始循环,结束循环) 2 跳过("") 3等待(等待时长)
                        map["Step"]=circleStepList[exeConfigList[i].value("step").toString()]["Step"].toString();
                        map["Info"]=QString("第%1次循环完成").arg(QString::number(a+1));
                        expSendList.insert(step,map);
                        step++;
                    }
                    i=circleStepList[exeConfigList[i].value("step").toString()]["Step"].toInt()-1;
                }
                else {
                    QString type=exeConfigList[i].value("type").toString();
                    QVariantMap map;

                    if(type=="1")//注射器
                    {
                        QString sql=QString("Select InsideDiameter,ReductionRatio,ScrewLead,CircleStep From SyringeMaintenance Where ConsumablesTypes='%1' and Id='%2'").arg(code,exeConfigList[i].value("value_1").toString());
                        query.exec(sql);
                        double InsideDiameter,ScrewLead,CircleStep;
                        QString ReductionRatio;
                        while (query.next()) {
                            InsideDiameter=query.value("InsideDiameter").toDouble();
                            ReductionRatio=query.value("ReductionRatio").toString();
                            ScrewLead=query.value("ScrewLead").toDouble();
                            CircleStep=query.value("CircleStep").toDouble();
                        }
                        double speed=exeConfigList[i].value("value_8").toDouble();

                        if(exeConfigList[i].value("value_9")=="mL/Min")// 速度单位:ml/分
                        {
                            speed=common->minToSecond(QString::number(speed),QString::number(InsideDiameter)).toDouble();
                        }

                        QStringList reList=ReductionRatio.split(':');

                        double stepNum=exeConfigList[i].value("value_6").toDouble()/ScrewLead*CircleStep*reList[1].toDouble();
                        double time=exeConfigList[i].value("value_6").toDouble()/speed;
                        double stepNumber= stepNum/time;

                        map["Type"]="0";//0 正常执行(Info发送指令) 1循环(开始循环,结束循环) 2 跳过("") 3等待(等待时长) 4检测器
                        map["Step"]=exeConfigList[i].value("step").toString();
                        map["Info"]=CommCommand::I().getSyring(QString::number(step),exeConfigList[i].value("value_1").toString(),exeConfigList[i].value("value_4").toString(),QString::number(stepNumber),QString::number(stepNum));
                        totalExpTime+=time;

                        expSendList.insert(step,map);
                        step++;
                    }
                    else if(type=="2")//阀门
                    {
                        map["Type"]="0";
                        map["Step"]=exeConfigList[i].value("step").toString();
                        map["Info"]= CommCommand::I().getValve(QString::number(step),exeConfigList[i].value("value_1").toString(),exeConfigList[i].value("value_2").toString());

                        totalExpTime+=1;

                        expSendList.insert(step,map);
                        step++;
                    }
                    else if(type=="3")//转盘
                    {
                        map["Type"]="0";
                        map["Step"]=exeConfigList[i].value("step").toString();
                        map["Info"]=CommCommand::I().getTurntable(QString::number(step),exeConfigList[i].value("value_1").toString());

                        totalExpTime+=1;

                        expSendList.insert(step,map);
                        step++;
                    }
                    else if(type=="4")//检测器
                    {
                        map["Type"]="4";
                        map["Step"]=exeConfigList[i].value("step").toString();
                        map["Info"]="";
                    }
                    else if(type=="5")//等待
                    {
                        map["Type"]="3";
                        map["Step"]=exeConfigList[i].value("step").toString();
                        map["Info"]=exeConfigList[i].value("value_1").toString();
                        totalExpTime+=exeConfigList[i].value("value_1").toDouble();

                        expSendList.insert(step,map);
                        step++;
                    }
                    else if(type=="7")//跳过
                    {
                        for(int m=0;m<=exeConfigList[i].value("value_1").toInt();m++)
                        {
                            QVariantMap map;
                            map["Type"]="2";//0 正常执行(Info发送指令) 1循环(开始循环,结束循环) 2 跳过("") 3等待(等待时长)
                            map["Step"]=QString::number(exeConfigList[i].value("step").toInt()+m);
                            map["Info"]="";
                            expSendList.insert(step,map);
                            step++;
                        }
                        i=exeConfigList[i].value("step").toInt()+exeConfigList[i].value("value_1").toInt()-1;
                    }
                    else if(type=="8")//盖盖
                    {
                        if(exeConfigList[i].value("value_1").toString()=="是"){
                            map["Type"]="0";
                            map["Step"]=exeConfigList[i].value("step").toString();
                            map["Info"]=CommCommand::I().coverTheLid(QString::number(step));
                            expSendList.insert(step,map);
                            totalExpTime+=2;

                        }
                        step++;
                    }
                    qDebug()<<QString::number(totalExpTime);
                }
            }
            udpClient->ClientSendingData(common->GetSendData( CommCommand::I().startExperiment()));
        }
        else if(Data=="0002")//停止实验
        {
            runningList.clear();
            udpClient->ClientSendingData(common->GetSendData( CommCommand::I().stopExperiment()));
        }
        else if(Data=="0003")//暂停
        {
            expStatus=2;
            udpClient->ClientSendingData(common->GetSendData( CommCommand::I().pauseExperiment()));
        }
        else if(Data=="0004")//继续
        {
            expStatus=1;
            udpClient->ClientSendingData(common->GetSendData( CommCommand::I().continueExperiment()));
        }
        else if(Data=="0005")//关机
        {

        }
        else if(Data=="0006")//fuwei
        {
            if(expStatus==0){
                udpClient->ClientSendingData(common->GetSendData( CommCommand::I().resetExpPos("0","0")));
            }
        }
    }
}

void speechModuleThread::serialclo(){
    serialPort->close();
}
